<template>
  <div class="clearfix">
    <a-upload :listType="listType" accept="image/*" :multiple="multiple" :data="{ biz: bizPath }" v-model:fileList="uploadFileList" :beforeUpload="beforeUpload" :disabled="disabled" @remove="handleDelete" @preview="handlePreview" :customRequest="customRequest">
      <!--      @change="handleChange"-->
      <div v-if="uploadVisible">
        <div v-if="listType == 'picture-card'">
          <LoadingOutlined v-if="loading" />
          <UploadOutlined v-else />
          <div class="ant-upload-text">{{ text }}</div>
        </div>
        <a-button v-if="listType == 'picture'" :disabled="disabled">
          <UploadOutlined />
          {{ text }}
        </a-button>
      </div>
    </a-upload>
    <a-modal :open="previewVisible" :title="previewTitle" :footer="null" @cancel="handleCancel">
      <img alt="example" style="width: 100%" :src="previewImage" />
    </a-modal>
  </div>
</template>
<script lang="ts">
  import { defineComponent, ref, computed, watch } from 'vue';
  import { LoadingOutlined, UploadOutlined } from '@ant-design/icons-vue';
  import { propTypes } from '/@/utils/propTypes';

  import { useMessage } from '/@/hooks/web/useMessage';
  import { useAttrs } from '@vben/hooks';
  import { Upload, Modal } from 'ant-design-vue';
  import { useMethods } from '@/hooks/system/useMethods';
  import { isArray, map, remove, isNil } from 'lodash-es';
  import { apiGetFileRemovePath } from '@/api/http/file/file.api';
  import { useRuleFormItem } from '@/hooks/component/useFormItem';

  const { createMessage } = useMessage();
  export default defineComponent({
    name: 'ImageUpload',
    components: { LoadingOutlined, UploadOutlined, [Upload.name]: Upload, [Modal.name]: Modal },
    inheritAttrs: false,
    props: {
      //绑定值
      value: propTypes.oneOfType([propTypes.string, propTypes.array, propTypes.number]),
      showUrl: propTypes.oneOfType([propTypes.string, propTypes.array]),
      //按钮文本
      listType: {
        type: String,
        required: false,
        default: 'picture-card',
      },
      //按钮文本
      text: {
        type: String,
        required: false,
        default: '上传',
      },
      //这个属性用于控制文件上传的业务路径
      bizPath: {
        type: String,
        required: false,
        default: 'temp',
      },
      //是否禁用
      disabled: {
        type: Boolean,
        required: false,
        default: false,
      },
      //上传数量
      fileMax: {
        type: Number,
        required: false,
        default: 1,
      },
    },
    emits: ['options-change', 'change', 'update:value'],
    setup(props, { emit }) {
      const attrs = useAttrs();
      const emitData = ref<any[]>([]);
      const fileUrls = ref<Array<{ url: string; title: string; fileid: string }>>([]);
      const [state] = useRuleFormItem(props, 'value', 'change', emitData);
      //获取文件名
      const getFileName = (path) => {
        if (path.lastIndexOf('\\') >= 0) {
          let reg = new RegExp('\\\\', 'g');
          path = path.replace(reg, '/');
        }
        return path.substring(path.lastIndexOf('/') + 1);
      };

      //上传状态
      const loading = ref<boolean>(false);
      //是否是初始化加载
      const initTag = ref<boolean>(true);
      //文件列表
      let uploadFileList = ref<any[]>([]);
      //预览图
      const previewImage = ref<string | undefined>('');
      //预览框状态
      const previewVisible = ref<boolean>(false);
      //预览框标题
      const previewTitle = ref<string>('');
      //计算是否开启多图上传
      const multiple = computed(() => {
        return props['fileMax'] > 1;
      });

      //计算是否可以继续上传
      const uploadVisible = computed(() => {
        return uploadFileList.value.length < props['fileMax'];
      });
      const getRandom = (length: number = 1) => {
        return '-' + parseInt(String(Math.random() * 10000 + 1), length);
      };
      /**
       * 监听value变化
       */
      watch(
        () => props.showUrl,
        (val) => {
          console.log(val, props.value);
          if (initTag.value == true) {
            if (!isNil(val)) {
              const urls = isArray(val) ? val : val.split(',');
              const fileid = String(props.value) as string;
              const ids = isArray(props.value) ? props.value : fileid.split(',');
              const fileArr: any = [];
              for (let i = 0; i < urls.length; i++) {
                fileArr.push({
                  url: urls[i],
                  fileid: ids[i],
                });
              }

              initFileList(fileArr);
            }
          }
        },
        { immediate: true },
      );

      /**
       * 初始化文件列表
       */
      function initFileList(paths: Array<{ url: string; title?: string; fileid: string }>) {
        if (!paths || paths.length == 0) {
          uploadFileList.value = [];
          return;
        }

        let files: any = [];
        paths.forEach((value) => {
          files.push({
            uid: getRandom(10),
            name: value.title || getFileName(value.url),
            status: 'done',
            url: value.url,
            fileid: value.fileid,
            response: {
              status: 'history',
              message: value.url,
            },
          });
        });
        uploadFileList.value = files;
      }

      /**
       * 上传前校验
       */
      function beforeUpload(file) {
        let fileType = file.type;
        if (fileType.indexOf('image') < 0) {
          createMessage.info('请上传图片');
          return false;
        }
      }
      /**
       * 文件上传结果回调
       */

      const { handleUploadFile } = useMethods();
      const customRequest = async (file) => {
        await handleUploadFile(file, '/file/upload', (res) => {
          fileUrls.value.push({ url: res.url, title: res.originalFilename, fileid: res.fileId });
          const ids = map(fileUrls.value, (item) => item.fileid).join(',');
          state.value = ids;
          emit('update:value', ids);
          initFileList(fileUrls.value);
        });
      };
      /**
       * 删除图片
       */
      async function handleDelete(file) {
        //如有需要新增 删除逻辑
        if (file.fileid) {
          await apiGetFileRemovePath(file.fileid);
        }
        remove(fileUrls.value, (item) => item.fileid == file.fileid);
        const ids = map(fileUrls.value, (item) => item.fileid).join(',');
        state.value = ids;
        emit('update:value', ids);
      }

      /**
       * 预览图片
       */
      function handlePreview(file) {
        previewImage.value = file.url || file.thumbUrl;
        previewTitle.value = file.name;
        previewVisible.value = true;
      }

      function handleCancel() {
        previewVisible.value = false;
      }

      return {
        attrs,
        previewImage,
        previewVisible,
        previewTitle,
        uploadFileList,
        multiple,
        loading,
        beforeUpload,
        uploadVisible,
        handlePreview,
        handleCancel,
        customRequest,
        handleDelete,
      };
    },
  });
</script>
<style scoped>
  .ant-upload-select-picture-card i {
    font-size: 32px;
    color: #999;
  }

  .ant-upload-select-picture-card .ant-upload-text {
    margin-top: 8px;
    color: #666;
  }
</style>
